package br.ufrpe.bsi.pvs.xml;

import java.io.File;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.jdom2.Element;
import org.jdom2.input.DOMBuilder;
import org.w3c.dom.Document;

import br.ufrpe.bsi.pvs.util.Util;

/** 
 * superclasse abstraca que tem como funcao unir o codigo dos leitores de
 * arquivos XML. os leitores extraem o conteudo do arquivo especificado nas
 * subclasses e os direciona para os interpretadores (parser) tambem especificados
 * nas subclasses, para que sejam processados.
 * 
 * esse leitor fica ligado o tempo todo, com uma thread em loop infinito lendo e,
 * quando acha conteudo relevante, chamando o interpretador especificado.
 */
public abstract class ReaderXML {

	/** gets the xml file for read */
	public abstract URL getXMLFile();

	/** gets the correct parser */
	public abstract ParserXML getParser();

	/** starts the reader thread */
	public void read() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						// processo burocratico para construir um Document
						DocumentBuilderFactory dbFactory = DocumentBuilderFactory
								.newInstance();
						DocumentBuilder dBuilder = dbFactory
								.newDocumentBuilder();
						URL url = getXMLFile();
						Document doc = dBuilder.parse(new File(url.toURI()));
						DOMBuilder domBuilder = new DOMBuilder();
						org.jdom2.Document docm = domBuilder.build(doc);

						// valida se o document eh relevante
						if (validateDOM(docm)) {
							// delega para a subclasse especificar o 
							// intepretador para processar o documento
							getParser().parse(docm);
						}
						
					} catch (Exception s) {
					}

					// espera 1250 milissegundos antes de fazer uma nova leitura
					Util.waitMillisseconds(1250);
				}
			}
		}).start();

	}

	/** validates the xml document if there's a request/response */
	private boolean validateDOM(org.jdom2.Document doc) {
		Element root = doc.getRootElement();
		return root.getName().equals(XMLUtil.ELEM_ROOT);
	}
}
